package com.alibaba.citrus.cr.unified.inventory.functions.handler;

import com.alibaba.citrus.cr.unified.inventory.model.enums.ReceiveStatus;
import com.alibaba.citrus.cr.unified.inventory.model.enums.ShipStatus;
import com.alibaba.citrus.cr.unified.inventory.utils.CompareUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.epoch.app.crunifiedinventory.model.enums.AllocateOrderStatus;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: yuhw
 * @date: 2024年01月23日 11:01
 **/
@Component("planAllocateOrderStatusCompute")
public class PlanAllocateOrderStatusCompute extends StatusCompute{
    private static Log log = Log.getLogger(PlanAllocateOrderStatusCompute.class);
    private static final String SPLIT = ":";

    private static Map<String,AllocateOrderStatus> statusMap = Maps.newHashMap();

    static {
        statusMap.put(key(ShipStatus.NONE,ReceiveStatus.NONE),AllocateOrderStatus.Shipment_Processing);
        statusMap.put(key(ShipStatus.NONE,ReceiveStatus.PART),AllocateOrderStatus.SHIPMENT_PROCESSING_PART_RECEIVED);
        statusMap.put(key(ShipStatus.NONE,ReceiveStatus.ALL),AllocateOrderStatus.SHIPMENT_PROCESSING_RECEIVED);
        statusMap.put(key(ShipStatus.PART,ReceiveStatus.NONE),AllocateOrderStatus.PART_SHIPPED_NONE_RECEIVED);
        statusMap.put(key(ShipStatus.PART,ReceiveStatus.PART),AllocateOrderStatus.PART_SHIPPED_PART_RECEIVED);
        statusMap.put(key(ShipStatus.PART,ReceiveStatus.ALL),AllocateOrderStatus.PART_SHIPPED_RECEIVED);
        statusMap.put(key(ShipStatus.ALL,ReceiveStatus.ALL),AllocateOrderStatus.COMPLETED);
        statusMap.put(key(ShipStatus.ALL,ReceiveStatus.PART),AllocateOrderStatus.ALL_SHIPPED_PART_RECEIVED);
        statusMap.put(key(ShipStatus.ALL,ReceiveStatus.NONE),AllocateOrderStatus.ALL_SHIPPED_NONE_RECEIVED);
    }
    //逆向得也要拆解一下

    @Override
    public AllocateOrderStatus process(ShipStatus shipStatus, ReceiveStatus receiveStatus, Map<String, AllocateOrderStatus> statusMap) {
        return statusMap.get(key(shipStatus,receiveStatus));
    }

    /**
     * 这个方法有局限性, 现用于计划调拨单, 且基本状态处于待发货之后的出库流程
     * @param statusList
     * @return
     */
    @Override
    public AllocateOrderStatus computeMainStatus(List<AllocateOrderStatus> statusList) {
        log.info("computeMainStatus_list:{}", JSON.toJSONString(statusList));
        //有部分发就是发,有收就是部分收
        /**
         * 有部分发 部分发
         * 有部分收 部分收
         * 还是先判断 全发 全收?
         */
        int shipNoneCount = 0;
        int shipPartCount = 0;
        int shipAllCount = 0;
        int receiveNoneCount = 0;
        int receivePartCount = 0;
        int receiveAllCount = 0;
        int cancelCount = 0;
        int draftCount = 0;
        int waitPushCount = 0;

        for (AllocateOrderStatus status : statusList) {
            switch (status){
                case Shipment_Processing:
                    shipNoneCount++;
                    receiveNoneCount++;
                    break;
                case SHIPMENT_PROCESSING_PART_RECEIVED:
                    shipNoneCount++;
                    receivePartCount++;
                    break;
                case SHIPMENT_PROCESSING_RECEIVED:
                    shipNoneCount++;
                    receiveAllCount++;
                    receivePartCount++;
                case PART_SHIPPED_NONE_RECEIVED:
                    shipPartCount++;
                    receiveNoneCount++;
                    break;
                case PART_SHIPPED_PART_RECEIVED:
                    shipPartCount++;
                    receivePartCount++;
                    break;
                case PART_SHIPPED_RECEIVED:
                    shipPartCount++;
                    receiveAllCount++;
                    receivePartCount++;
                    break;
                case ALL_SHIPPED_NONE_RECEIVED:
                    shipAllCount++;
                    shipPartCount++;
                    receiveNoneCount++;
                    break;
                case ALL_SHIPPED_PART_RECEIVED:
                    shipAllCount++;
                    shipPartCount++;
                    receivePartCount++;
                    break;
                case COMPLETED:
                    shipAllCount++;
                    receiveAllCount++;
                    //这里如果已完成,其实收货都能算已经部分收发了, 因为这里计算的是主单状态
                    shipPartCount++;
                    receivePartCount++;
                    break;
                case WAIT_PUSH:
                    waitPushCount++;
                    break;
                case Cancel:
                    cancelCount++;
                    break;
                case Shipped:
                    shipAllCount++;
                    receiveNoneCount++;
                    break;
                case Part_Shipped:
                    shipPartCount++;
                    break;
                default:
            }
        }
        boolean allWaitPush = statusList.stream().allMatch(status -> AllocateOrderStatus.WAIT_PUSH.equals(status));
        boolean allCancel = statusList.stream().allMatch(status -> AllocateOrderStatus.Cancel.equals(status));
        long count = statusList.stream().filter(status -> !CompareUtil.anyOf(status, AllocateOrderStatus.Cancel, AllocateOrderStatus.WAIT_PUSH)).count();
        log.info("allWaitPush:{},allCancel:{},count:{},shipAllCount:{},receiveAllCount:{},shipPartCount:{},receivePartCount:{}," +
                "shipNoneCount:{},receiveNoneCount:{}",allWaitPush,allCancel,count,shipAllCount,receiveAllCount,shipPartCount,receivePartCount,shipNoneCount,receiveNoneCount);
        if (allCancel){
            return AllocateOrderStatus.Cancel;
        }else if (allWaitPush){
            return AllocateOrderStatus.WAIT_PUSH;
        }else if (shipAllCount == count && receiveAllCount == count){
            //已完成
            return AllocateOrderStatus.COMPLETED;
        }else if (shipAllCount == count && receivePartCount > 0){
            //
            return AllocateOrderStatus.ALL_SHIPPED_PART_RECEIVED;
        }else if (shipAllCount == count && receiveNoneCount == count){
            return AllocateOrderStatus.ALL_SHIPPED_NONE_RECEIVED;
        }else if (shipPartCount > 0  && receiveAllCount == count){
            return AllocateOrderStatus.PART_SHIPPED_RECEIVED;
        }else if (shipPartCount > 0 && receivePartCount > 0){
            return AllocateOrderStatus.PART_SHIPPED_PART_RECEIVED;
        }else if (shipPartCount > 0 && receiveNoneCount == count){
            return AllocateOrderStatus.PART_SHIPPED_NONE_RECEIVED;
        }else if (shipNoneCount == count && receiveAllCount == count){
            return AllocateOrderStatus.SHIPMENT_PROCESSING_RECEIVED;
        }else if (shipNoneCount == count && receivePartCount > 0){
            return AllocateOrderStatus.SHIPMENT_PROCESSING_PART_RECEIVED;
        }else if (shipNoneCount == count && receiveNoneCount == count){
            return AllocateOrderStatus.Shipment_Processing;
        }
        //TODO 如果都没有匹配上是否会有变化
        return null;
    }

    @Override
    public Map<String,AllocateOrderStatus> getStatusMap() {
        //TODO 状态需要补全
        return statusMap;
    }

    private static String key(ShipStatus shipStatus, ReceiveStatus receiveStatus){
        return shipStatus.name() + SPLIT + receiveStatus.name();
    }
}
